home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 036 (1987-11-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 036 (1987-11-15)(Ossowski, Stefan)(DE)(PD).adf / Xicon / xicon.c < prev    next >
C/C++ Source or Header  |  1989-01-18  |  14KB  |  473 lines

  1. /*****************************************************************
  2.  *                                                               *
  3.  *    XICON V2.00                                                *
  4.  *                                                               *
  5.  *   Runs Command Script Files from an Icon                      *
  6.  *                                                               *
  7.  *   copyright 1986, 1987 by Pete Goodeve -- All Rights Reserved *
  8.  *                                                               *
  9.  *    Compile with pass2 -v option (Lattice)                     *
  10.  *    Link with lstartup.obj, amiga.lib, lc.lib                  *
  11.  *                                                               *
  12.  * vers 87:5:13                                                  *
  13.  *****************************************************************/
  14.  
  15. #include "exec/types.h"
  16. #include "exec/exec.h"
  17. #include "workbench/startup.h"
  18. #include "workbench/workbench.h"
  19. #include "workbench/icon.h"
  20. #include "libraries/dosextens.h"
  21.  
  22. LONG IntuitionBase;
  23. int V1_2 = FALSE;
  24. LONG IconBase;
  25.  
  26.  
  27. extern struct Window  *findwindow();
  28.  
  29. extern struct WBStartup *WBenchMsg;
  30.  
  31. struct WBArg *argptr;
  32. int nargs;
  33. int autoclose=TRUE, /* will be FALSEified by non-use of 'closewindow' */
  34.     usescript=TRUE, usewindow = TRUE, istext = FALSE;
  35. int abortmark = FALSE;
  36.  
  37. #define MAXDESCR 120
  38. char ConDescr[MAXDESCR+4] = "CON:0/10/640/185/XICON 2.00";
  39.              /* available for later fiddling */
  40. #define MAXTITLE 100
  41. char Title[MAXTITLE];
  42.  
  43. LONG outfile = NULL;
  44. extern struct Window *conWindow;
  45. extern struct ConUnit *conUnit;
  46. LONG windowsig;
  47.  
  48. /** Close Gadget structure */
  49.  
  50. LONG Close_Data[] = { /* move to chip ram before use */
  51.  0x3FFFFC80,
  52.  0x30000C80,
  53.  0x33FFCC80,
  54.  0x33FFCC80,
  55.  0x33C3CC80,
  56.  0x33C3CC80,
  57.  0x33FFCC80,
  58.  0x33FFCC80,
  59.  0x30000C80,
  60.  0x3FFFFC80,
  61.  
  62.  0x00000000,
  63.  0x00000000,
  64.  0x00000000,
  65.  0x00000000,
  66.  0x003C0000,
  67.  0x003C0000,
  68.  0x00000000,
  69.  0x00000000,
  70.  0x00000000,
  71.  0x00000000
  72. };
  73.  
  74.  
  75. struct Image Close_Image = {
  76.  0, 0, /* Left, Top  */
  77.  0x0019, 0x000A, 2, /* Width, Height, Depth */
  78.  NULL, /* filled in to point to image in chip ram */
  79.  3, 0,
  80.  NULL
  81. };
  82.  
  83. struct Gadget Close_Gadg = {
  84.    NULL,    /* pointer to Next Gadget */
  85.    4, 0, 0x019, 0x0A,  /* (Left Top Width Height) Hit Box */
  86.    GADGHCOMP | GADGIMAGE,   /* Flags */
  87.    /* Activation flags */
  88.    RELVERIFY,
  89.    SYSGADGET | CLOSE,       /* Type (!) */
  90.    (APTR)&Close_Image,    /* pointer to GadgetRender */
  91.    NULL,             /* no pointer to SelectRender */
  92.    NULL,             /* no pointer to GadgetText */
  93.    0,                /* no MutualExclude */
  94.    NULL,             /* no pointer to SpecialInfo */
  95.    0,                /* no ID */
  96.    NULL              /* no pointer to special data */
  97. };
  98.  
  99. /* Continue Gadget structure */
  100.  
  101. struct IntuiText Cont_Text = {
  102.    3,0,        /* front, back pens */
  103.    JAM2,    /* draw mode */
  104.    10,1,    /* left, top edge */
  105.    NULL,    /* default font */
  106.    NULL,    /* text string -- filled in before use */
  107.    NULL        /* no next */
  108. };
  109.  
  110. struct Gadget Cont_Gadg = {
  111.    NULL,    /* pointer to Next Gadget */
  112.    0, -9, 0, 9,  /* (Left Top Full-Width Height) Hit Box */
  113.    GADGHCOMP | GRELWIDTH | GRELBOTTOM ,   /* Flags */
  114.    /* Activation flags */
  115.    RELVERIFY,
  116.    BOOLGADGET,       /* Type */
  117.    NULL,        /* no pointer to GadgetRender */
  118.    NULL,             /* no pointer to SelectRender */
  119.    &Cont_Text,       /*  pointer to GadgetText */
  120.    0,                /* no MutualExclude */
  121.    NULL,             /* no pointer to SpecialInfo */
  122.    0,                /* no ID */
  123.    NULL              /* no pointer to special data */
  124. };
  125.  
  126. _main() /* bypasses standard C startup code */
  127. {
  128.  
  129.    if (!WBenchMsg)
  130.       return 0;
  131.  
  132.    if (IntuitionBase = OpenLibrary("intuition.library",33)) V1_2 = TRUE;
  133.     else IntuitionBase = OpenLibrary("intuition.library",0);
  134.    IconBase = OpenLibrary(ICONNAME,1); /* doesn't matter much if not there */
  135.  
  136.  
  137.    argptr = WBenchMsg->sm_ArgList;
  138.    nargs = WBenchMsg->sm_NumArgs;
  139.    /* Skip the first arg (the program itself) and process the rest */
  140.    for(argptr++, nargs--; nargs; argptr++, nargs--)
  141.       if (!doito(argptr)) goto clean_exit; /* sometimes a goto is good */
  142.  
  143.    SetSignal(0, SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | windowsig);
  144.    if (usewindow && !autoclose) {
  145.       Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | windowsig);
  146.    }
  147.  
  148. clean_exit:
  149.    dump_window();
  150.  
  151.    if (outfile) Close(outfile);
  152.    if (IconBase) CloseLibrary(IconBase);
  153.    CloseLibrary(IntuitionBase); /* this is in "ROM" (so no check needed) */
  154. }
  155. /*** end main ***/
  156.  
  157. /************************************************************
  158.  * In the code below, I don't follow the usual method of    *
  159.  * passing each command string in turn to Execute.  Instead *
  160.  * I pass the entire command file as the new input stream,  *
  161.  * which Execute accepts after processing the null string   *
  162.  * it gets as a "command".  This avoids the system having   *
  163.  * to reload the DOS "RUN" module for every line of the     *
  164.  * command file, though on the other hand it does lock out  *
  165.  * the possibility of redirecting keyboard input through    *
  166.  * the "current window" to the command.  I thought the      *
  167.  * trade-off was worth it.                                  *
  168.  ************************************************************/
  169.  
  170. doito(argp) struct WBArg *argp;
  171. {
  172.    LONG oldir;
  173.  
  174.    oldir = CurrentDir(argp->wa_Lock);
  175.    if (!readtt(argp) || abortmark) return FALSE;
  176.    if (istext) dispfile(argp->wa_Name);
  177.    else if (usescript)
  178.       if (!execfile(argp->wa_Name)) return FALSE;
  179.             /* I don't see how that could happen, but...*/
  180.    CurrentDir(oldir);
  181.    return TRUE;
  182. }
  183.  
  184.  
  185. execfile(fname) char *fname;
  186. {
  187.    LONG infile;
  188.    infile = Open(fname, MODE_OLDFILE);
  189.    if (!infile) return FALSE;
  190.    Execute("", infile, outfile);
  191.    Close(infile);
  192.    return TRUE;
  193. }
  194.  
  195.  
  196. /* Read ToolTypes of current icon */
  197.  
  198. readtt(argp) struct WBArg *argp;
  199. {
  200.    struct DiskObject *iconobj=NULL, *GetDiskObject();
  201.    char **toolarray, *FindToolType();
  202.    char *modes, *windowstring, *titlestring, *locdir;
  203.    LONG dirfile;
  204.  
  205.    if (!IconBase) {
  206.       if (!get_window(ConDescr)) return FALSE;
  207.       display("Icon Library not found -- ignoring ToolTypes\n");
  208.       return TRUE; /* just soldier on...*/
  209.    }
  210.    /* we don't do any checks here for icon type -- probably should...*/
  211.    if (!(iconobj = GetDiskObject(argp->wa_Name))) {
  212.       display("COULDN'T GET INFO FOR ICON!!\n");
  213.       return TRUE;
  214.    }
  215.    toolarray = iconobj->do_ToolTypes;
  216.    modes = FindToolType(toolarray,"MODE");
  217.    autoclose &= MatchToolValue(modes,"closewindow");
  218.          /* ALL must agree to close the window automatically */
  219.    usescript = !MatchToolValue(modes,"noscript");
  220.    istext = MatchToolValue(modes,"text");
  221.  
  222.    if (windowstring = FindToolType(toolarray,"WINDOW"))
  223.     strncpy(&ConDescr[4], windowstring, MAXDESCR); /* append to 'CON:' */
  224.     /* the above is probably a Lattice special...*/
  225.    if (!outfile) {
  226.     usewindow = !MatchToolValue(modes,"nowindow");
  227.     if (usewindow)
  228.       get_window(ConDescr);
  229.     else
  230.       outfile = Open("NIL:", MODE_OLDFILE);
  231.    }
  232.    if (!outfile) return FALSE;
  233.  
  234.    if (conWindow && (titlestring = FindToolType(toolarray,"TITLE"))) {
  235.     strncpy(Title, titlestring, MAXTITLE);
  236.     /* Note that SetWindowTitles does NOT copy the string! */
  237.     SetWindowTitles(conWindow, Title, -1);
  238.    }
  239.    if ((locdir = FindToolType(toolarray,"LOCDIR")) &&
  240.        (dirfile = Open(locdir,MODE_NEWFILE)))
  241.    {
  242.         Write(dirfile,"\"",1);
  243.         traverse(argp->wa_Lock, dirfile);
  244.         Write(dirfile,"\"\n",2);
  245.         Close(dirfile);
  246.    }
  247.    dotoolcmds(toolarray); /* some tooltypes may be commands */
  248.    FreeDiskObject(iconobj);
  249.    return TRUE;
  250. }
  251.  
  252.  
  253. /* Execute any commands specified in the ToolTypes */
  254.  
  255. dotoolcmds(toolarray) char **toolarray;
  256. {
  257.    char *holdnext, *toolstr, *FindToolType();
  258.    LONG lock;
  259.    while (*toolarray) {
  260.       holdnext = toolarray[1];
  261.       toolarray[1] = NULL;
  262.       if (!abortmark) {
  263.         if (toolstr=FindToolType(toolarray,"REM")) {
  264.            display(toolstr);
  265.            display("\n");
  266.         }
  267.         else if (toolstr=FindToolType(toolarray,"TEXT"))
  268.            dispfile(toolstr);
  269.         else if (toolstr=FindToolType(toolarray,"CMD"))
  270.            Execute(toolstr,0,outfile);
  271.         else if (toolstr=FindToolType(toolarray,"SCRIPT"))
  272.            execfile(toolstr);
  273.         else if (!strcmp(*toolarray,"PAUSE")) /*FindT-T- needs "=" */
  274.            abortmark = pausekey();
  275.         else if (toolstr=FindToolType(toolarray,"EXISTS")) {
  276.        if (lock = Lock(toolstr,ACCESS_READ)) UnLock(lock);
  277.            else abortmark = TRUE;
  278.         }
  279.       } /* end !abortmark */
  280.       else /* abort has been signalled */ {
  281.         if (toolstr=FindToolType(toolarray,"ABORT-REM")) {
  282.            display(toolstr);
  283.            display("\n");
  284.         }
  285.         else if (toolstr=FindToolType(toolarray,"ABORT-TEXT"))
  286.            dispfile(toolstr);
  287.         else if (toolstr=FindToolType(toolarray,"ABORT-CMD"))
  288.            Execute(toolstr,0,outfile);
  289.         else if (toolstr=FindToolType(toolarray,"ABORT-SCRIPT"))
  290.            execfile(toolstr);
  291.         else if (!strcmp(*toolarray,"ABORT-PAUSE"))
  292.            abortmark = pausekey();
  293.         else if (!strcmp(*toolarray,"RESTORE"))
  294.            abortmark = FALSE;
  295.       }
  296.       *++toolarray = holdnext; /* restore next item & move to it */
  297.    }
  298. }
  299.  
  300.  
  301. traverse(lock, dirfile) LONG lock, dirfile;
  302. {
  303.    int level;
  304.    struct DeviceList *volp;
  305.    struct FileLock *lockp;
  306.    char *namep;
  307.    struct FileInfoBlock *fib;
  308.    if (lock) {
  309.       fib = AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC | MEMF_CLEAR);
  310.       if (!fib) return 2; /* ...being lazy */
  311.       level = traverse(ParentDir(lock), dirfile);
  312.       if (level > 1) /* there is a superior non-root directory */
  313.            Write(dirfile, "/", 1);
  314.       if (level == 0) /* this was the root directory */ {
  315.         /* all this to overcome RAM: handler bug...*/
  316.         lockp = (struct FileLock *)BADDR(lock);
  317.         volp = (struct DeviceList *)BADDR(lockp->fl_Volume);
  318.         namep = (char *)BADDR(volp->dl_Name);
  319.         Write(dirfile, namep+1, *namep);
  320.         Write(dirfile, ":", 1);
  321.       }
  322.       else {
  323.           if (Examine(lock,fib))
  324.             Write(dirfile,fib->fib_FileName,strlen(fib->fib_FileName));
  325.       }
  326.       FreeMem(fib,sizeof(struct FileInfoBlock));
  327.       return level+1;
  328.    }
  329.    else return 0;
  330. }
  331.  
  332. get_window(windescr) char *windescr;
  333. {
  334.    if (outfile) /* already open */ return TRUE;
  335.  
  336.    outfile = Open(windescr, MODE_OLDFILE);
  337.  
  338.    if (!outfile) return FALSE;
  339.  
  340.    if (!findWindow(outfile)) return FALSE;
  341.  
  342.    if (!(Close_Image.ImageData = AllocMem(sizeof(Close_Data), MEMF_CHIP)))
  343.     return TRUE; /* just ignore close gadget */
  344.    /* the following may be a Lattice special..?*/
  345.    movmem(Close_Data, Close_Image.ImageData, sizeof(Close_Data));
  346.    ModifyIDCMP(conWindow, CLOSEWINDOW); /* Heh..again*/
  347.    windowsig = 1<<(conWindow->UserPort->mp_SigBit);
  348.    conWindow->Flags |= WINDOWCLOSE; /* Heh heh! */
  349.    AddGadget(conWindow, &Close_Gadg, 0); /* Must be on TOP of drag gadget */
  350.    if (V1_2)
  351.     RefreshWindowFrame(conWindow);
  352.    else {
  353.     SetWindowTitles(conWindow, conWindow->Title, -1);
  354.     RefreshGadgets(&Close_Gadg, conWindow, NULL);
  355.    }
  356.    return TRUE;
  357. } /* get_window */
  358.  
  359. dump_window()
  360. {
  361.    if (!Close_Image.ImageData) return;
  362.    ModifyIDCMP(conWindow, 0);
  363.    RemoveGadget(conWindow, &Close_Gadg);
  364.    FreeMem(Close_Image.ImageData, sizeof(Close_Data));
  365.    /* file & window are closed at a higher level */
  366. }
  367.  
  368.  
  369. display(msg) char *msg;
  370. {
  371.    Write(outfile, msg, strlen(msg));
  372. }
  373. /**************************************/
  374.  
  375.  
  376. #define BUFSIZE 200
  377.  
  378. LONG textfile;
  379. static int curmax = 0;
  380.  
  381. dispfile(fname) char *fname;
  382. {
  383.    char inbuf[BUFSIZE], outbuf[BUFSIZE], ansbuf[2];
  384.    int inpos = 0, lcount = 20;
  385.    curmax = 0;
  386.    textfile = Open(fname, MODE_OLDFILE);
  387.    if (!textfile || !conWindow) return FALSE;
  388.    ModifyIDCMP(conWindow, conWindow->IDCMPFlags | RAWKEY);
  389.    while (copyline(inbuf, &inpos, outbuf)) {
  390.       if (!lcount-- || *outbuf == '\014' /*Formfeed*/) {
  391.       if (pausekey()) goto cutit; /* just continues unless CLOSE */
  392.          display(outbuf);
  393.          lcount = 15; /* leave some overlap with previous page */
  394.       }
  395.       else display(outbuf);
  396.    }
  397.   cutit:
  398.    Close(textfile);
  399.    ModifyIDCMP(conWindow, conWindow->IDCMPFlags & ~RAWKEY);
  400. }
  401.  
  402. copyline(in, pos, out) char *in, *out; int *pos;
  403. {
  404.    char ch, copych();
  405.    int trunc=BUFSIZE-1;
  406.    while ((*out++ = ch = copych(in, pos)) && ch != '\n' && --trunc)
  407.        /*loop*/;
  408.    *out = '\0';
  409.    return (int) ch /* FALSE if EOF */;
  410. }
  411.  
  412.  
  413. char copych(in, pos) char *in; int *pos;
  414. {
  415.    if (*pos >= curmax) {
  416.       curmax = Read(textfile,in,BUFSIZE);
  417.       *pos = 0;
  418.       if (!curmax) return '\0';
  419.    }
  420.    return in[(*pos)++];
  421. }
  422.  
  423. pausekey()
  424. {
  425.     int code;
  426.     Cont_Text.IText = "to CONTINUE -- Click here or Type any key";
  427.     AddGadget(conWindow, &Cont_Gadg, -1);
  428.     RefreshGadgets(&Cont_Gadg, conWindow, NULL);
  429.     code = pause(RAWKEY | GADGETUP);
  430.     Cont_Text.IText = "                                          ";
  431.            /* seems crude, but it's all I can figger.. */
  432.     RefreshGadgets(&Cont_Gadg, conWindow, NULL);
  433.     RemoveGadget(conWindow, &Cont_Gadg);
  434.     return code;
  435. }
  436.  
  437. #define CODE_C 0x033 
  438.  
  439. pause(evmask) ULONG evmask; /* waits for a relevant event from the window */
  440.                   /* if it is a CLOSEWINDOW or cntrl-C it returns TRUE,
  441.                      otherwise FALSE */
  442. {
  443.    struct IntuiMessage *eventmsg, *GetMsg();
  444.    ULONG oldIDCMP, class, mark = FALSE;
  445.    USHORT code, qual;
  446.    if (!conWindow) return FALSE; /* only wait if there's a window */
  447.    oldIDCMP = conWindow->IDCMPFlags;
  448.    if (evmask) ModifyIDCMP(conWindow, conWindow->IDCMPFlags | evmask);
  449.    do {
  450.      Wait(windowsig);
  451.      while(eventmsg = GetMsg(conWindow->UserPort)) {
  452.        class = eventmsg->Class;
  453.        code = eventmsg->Code;
  454.        qual = eventmsg->Qualifier;
  455.        ReplyMsg(eventmsg);
  456.        if((class == CLOSEWINDOW) ||
  457.           (class == RAWKEY && (qual & IEQUALIFIER_CONTROL) && code == CODE_C ))
  458.        {
  459.           mark = TRUE;
  460.           break;
  461.        }
  462.  
  463.      }
  464.    } while ((class == RAWKEY) && (code & IECODE_UP_PREFIX));
  465.                /* ignore left-over key-ups */ 
  466.   if (evmask) ModifyIDCMP(conWindow, oldIDCMP);
  467.    return mark;
  468. }
  469.  
  470. /**************************************/
  471.  
  472.  
  473.